﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Input;

namespace Cube2
{
    /// <summary>
    /// Moi khi tao 1 list doi tuong thi ta tao them 1 list ao cho no nua
    /// </summary>
    public class Ship
    {
        public List<CModel> listShip;//0 player,1 tau me
        public List<CModel> listEnemie;
        public List<CModel> listCheckShipMother;//check ship+mother
        public List<CModel> listCheckEnemies;
        public List<CModel> listGround;
        public List<CModel> listBullet;
        List<int> bloodEnemies= new List<int>();
       


        private float lastTimeBullet=0;
        private float nowTime;
        private int khauSung = 1;

        List<Matrix> tempRotation = new List<Matrix>();

        CCamera camera;
        public Ship()
        {
            listShip= new List<CModel>();
            listEnemie = new List<CModel>();
            listCheckShipMother = new List<CModel>();
            listGround = new List<CModel>();
            listCheckEnemies = new List<CModel>();
            listBullet = new List<CModel>();
        }
        /// <summary>
        /// Load Content Game Ship
        /// </summary>
        /// <param name="Content"></param>
        /// <param name="graphicsDevice"></param>


        public void LoadContent(ContentManager Content,GraphicsDevice graphicsDevice)
        {
            Vector3 position = new Vector3(0, 0, 0);//vị trí vật
            Vector3 rotation = new Vector3(0, MathHelper.ToRadians(0), 0);//góc quay ban đầu
            #region Ship
            CModel model = new CModel(Content.Load<Model>("Models\\ship"), position + new Vector3(0, 0,0), rotation, new Vector3(0.25f), graphicsDevice);//tạo vật
            listShip.Add(model);//add vào list
            //Check player
            CModel checkPlayer = new CModel(Content.Load<Model>("Models\\cau"), new Vector3(1000, 1000, 1000), Vector3.Zero, new Vector3(150.0f), graphicsDevice);
            listCheckShipMother.Add(checkPlayer);

            //Mother
            CModel shipMother = new CModel(Content.Load<Model>("Models\\ship"), position + new Vector3(0, 0, -2000), rotation, new Vector3(0.50f), graphicsDevice);//tạo vật
            listShip.Add(shipMother);
            CModel checkShipMother = new CModel(Content.Load<Model>("Models\\cau"), new Vector3(1000, 1000, 1000), Vector3.Zero, new Vector3(300.0f), graphicsDevice);
            listCheckShipMother.Add(checkShipMother);

            CModel ground = new CModel(Content.Load<Model>("Models\\Ground"), new Vector3(0, -1000, 0), new Vector3(0, 0, 0), new Vector3(0.25f), graphicsDevice);
            listGround.Add(ground);
            #endregion

            #region enemie
            for (int i = 0; i < Const.NUMBER_OF_ENEMIES; i++)
            {
                CModel modelEnemie = new CModel(Content.Load<Model>("Models\\ship"), position + new Vector3(i*1000, 0, 0), rotation, new Vector3(0.25f), graphicsDevice);//tạo vật

                listEnemie.Add(modelEnemie);
                bloodEnemies.Add(Const.BLOOD_ENEMIE);
            }

            //Check
            for (int i = 0; i < listEnemie.Count; i++)
            {
                CModel checkEnemie = new CModel(Content.Load<Model>("Models\\cau"), Vector3.Zero, Vector3.Zero, new Vector3(150.0f), graphicsDevice);
                listCheckEnemies.Add(checkEnemie);
            }
            #endregion

            camera = new ChaseCamera(new Vector3(0, 400, 1500), new Vector3(0, 200, 0), new Vector3(0, 0, 0), graphicsDevice);

           
        }

        /// <summary>
        /// Move ship by keyboards
        /// </summary>
        /// <param name="gameTime"></param>
        public void MoveShip(GameTime gameTime)
        {
            Vector3 rotChange = new Vector3(0, 0, 0);

            if (Keyboard.GetState().IsKeyDown(Keys.S))
                rotChange += new Vector3(-1, 0, 0);
            if (Keyboard.GetState().IsKeyDown(Keys.W))
                rotChange += new Vector3(1, 0, 0);
            if (Keyboard.GetState().IsKeyDown(Keys.A))
                rotChange += new Vector3(0, 1, 0);
            if (Keyboard.GetState().IsKeyDown(Keys.D))
                rotChange += new Vector3(0, -1, 0);
            listShip[0].Rotation += rotChange * 0.025f;
            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
                listShip[0].Positon = listShip[0].Rotation = Vector3.Zero;
            Matrix rotation = Matrix.CreateFromYawPitchRoll(listShip[0].Rotation.Y, listShip[0].Rotation.X, listShip[0].Rotation.Z);
            listShip[0].Positon += Vector3.Transform(Vector3.Forward, rotation) * (float)gameTime.ElapsedGameTime.TotalMilliseconds;//di chuyen
           
            if (Keyboard.GetState().IsKeyDown(Keys.Space))//space chay nhanh
                listShip[0].Positon += Vector3.Transform(Vector3.Forward, rotation) * (float)gameTime.ElapsedGameTime.TotalMilliseconds*10 ;
            
            if (Keyboard.GetState().IsKeyDown(Keys.X))//X giat lui
                listShip[0].Positon -= Vector3.Transform(Vector3.Forward, rotation) * (float)gameTime.ElapsedGameTime.TotalMilliseconds*4 ;
            listCheckShipMother[0].Positon = listShip[0].Positon;
            listCheckShipMother[1].Positon = listShip[1].Positon;
            for (int i = 0; i < Const.NUMBER_OF_ENEMIES; i++)
            {
                listCheckEnemies[i].Positon= listEnemie[i].Positon;
            }
            //check colision
            CheckCollision();
        }
       
        /// <summary>
        /// Chek Va cham cua player (chi moi xet cua player thoi)
        /// </summary>
        public void CheckCollision()
        {
            for (int i = 1; i < listCheckShipMother.Count; i++)
            {
                if (listCheckShipMother[0].CheckColision(listCheckShipMother[i]))//neu va cham thi doi huong
                    listShip[0].Rotation += new Vector3(0, -1, 0) * 0.05f;
            }
            foreach (var enemie in listCheckEnemies)
            {
                if (listCheckShipMother[0].CheckColision(enemie))
                {
                    listShip[0].Rotation += new Vector3(0, -1, 0) * 0.05f;
                }
            }
        }
        /// <summary>
        /// Di chuyen tat ca enemie
        /// </summary>
        /// <param name="gameTime"></param>
        public void MoveShipEnemie(GameTime gameTime)
        {
            Random ran = new Random();
            for (int i = 0; i < listEnemie.Count; i++)
            {
                if (bloodEnemies[i]>0)
                {
                    Matrix rotation = Matrix.CreateFromYawPitchRoll(listEnemie[i].Rotation.Y, listEnemie[i].Rotation.X, listEnemie[i].Rotation.Z);
                    listEnemie[i].Positon += Vector3.Transform(Vector3.Forward, rotation) * (float)gameTime.ElapsedGameTime.TotalMilliseconds * 4;
                    int n = ran.Next(10);
                    int y = ran.Next(2);
                    listEnemie[i].Rotation += new Vector3(0, y, 0) * (float)n / 1000;
                }
                
            }
                
            
        }
        public void CreateBullet(ContentManager Content, GraphicsDevice graphicsDevice,GameTime gameTime)
        {
            nowTime = (float)gameTime.TotalGameTime.TotalMilliseconds;
            if (Mouse.GetState().LeftButton == ButtonState.Pressed)
                isBullet = true;
            else
                isBullet = false;
            if (isBullet)
            {
               
                if (nowTime-lastTimeBullet>Const.TIME_WAIT_FOR_NEXT_BULLET)
                {

                    Matrix rotationBullet = Matrix.CreateFromYawPitchRoll(listShip[0].Rotation.Y,listShip[0].Rotation.X,listShip[0].Rotation.Z);
                    Vector3 positionOffSet1 = Vector3.Transform(new Vector3(100,0,200), rotationBullet);
                    Vector3 positionOffSet2 = Vector3.Transform(new Vector3(-100, 0, 200), rotationBullet);
                    if (khauSung == 1)
                    {
                        CModel bullet = new CModel(Content.Load<Model>("Models\\cau"), listShip[0].Positon + positionOffSet1, Vector3.Zero, new Vector3(20.0f), graphicsDevice);//tao bullet
                        Matrix rotation = Matrix.CreateFromYawPitchRoll(listShip[0].Rotation.Y, listShip[0].Rotation.X, listShip[0].Rotation.Z);
                        tempRotation.Add(rotation);
                        listBullet.Add(bullet);
                        khauSung = 2;
                    }
                    else
                    {
                        CModel bullet = new CModel(Content.Load<Model>("Models\\cau"), listShip[0].Positon + positionOffSet2, Vector3.Zero, new Vector3(20.0f), graphicsDevice);//tao bullet
                        Matrix rotation = Matrix.CreateFromYawPitchRoll(listShip[0].Rotation.Y, listShip[0].Rotation.X, listShip[0].Rotation.Z);
                        tempRotation.Add(rotation);
                        listBullet.Add(bullet);
                        khauSung = 1;
                    }
                    
                    
                    lastTimeBullet = nowTime;
                }
                       
            }

            if (listBullet.Count > 0)
            {
                for (int i = 0; i < listBullet.Count; i++)
                {
                    MoveBullet(listBullet[i], gameTime, tempRotation[i]);
                    if (listBullet[i].Positon.Y < -40000 || listBullet[i].Positon.Y > 40000 || listBullet[i].Positon.X > 40000 || listBullet[i].Positon.X < -40000 || listBullet[i].Positon.Z < -40000 || listBullet[i].Positon.Z > 40000)
                    {
                        listBullet.Remove(listBullet[i]);
                        tempRotation.Remove(tempRotation[i]);
                    }
                }
            }
            
            
        }

        public void ProcessCollisonBullet()
        {
            foreach (var item in listBullet)
	        {
                if (listCheckShipMother[1].CheckColision(item))
                {
                    Const.BLOOD_MOTHER-=Const.SUB_BLOOD;
                }
            
	        }
            if (Const.BLOOD_MOTHER<=0)
            {
                Const.BLOOD_MOTHER = 0;

                if (listShip[1].Positon.Y >= -1000)
                {
                    listShip[1].Positon += 10 * Vector3.Down;
                    listShip[1].Rotation += Vector3.Left / 100;
                }
                else
                {
                    
                }
            }
            //
            foreach (var item in listBullet)
            {
                for (int i = 0; i < listCheckEnemies.Count; i++)
                {
                    if (listCheckEnemies[i].CheckColision(item))
                    {
                        bloodEnemies[i] -= Const.SUB_BLOOD;
                    }
                }
            }
            for (int i = 0; i < listEnemie.Count; i++)
            {
                if (bloodEnemies[i]<=0)
                {
                    bloodEnemies[i] = 0;
                    if (listEnemie[i].Positon.Y>=-2000)
                    {
                        listEnemie[i].Positon += 10 * Vector3.Down;
                        listEnemie[i].Rotation += Vector3.Left / 70;
                    }
                }
            }

            
        }
        public void MoveBullet(CModel model, GameTime gameTime, Matrix rotation)
        {           
            //Matrix rotation = Matrix.CreateFromYawPitchRoll(listShip[0].Rotation.Y, listShip[0].Rotation.X, listShip[0].Rotation.Z);
            model.Positon += Vector3.Transform(Vector3.Forward, rotation) * (float)gameTime.ElapsedGameTime.TotalMilliseconds * Const.VIOLENTCY_OF_BULLET;
            if (camera.BoudingVolumeslnView(model.BoudingSphere))
            {
                   model.Draw(camera.View, camera.Projection);
            }
            
        }

        /// <summary>
        /// update camera
        /// </summary>
        public void updateChaseCamera()
        {
            ((ChaseCamera)camera).Move(listShip[0].Positon, listShip[0].Rotation);
            camera.Update();
        }
        public void Update(GameTime gameTime)
        {
            MoveShip(gameTime);
            updateChaseCamera();
            MoveShipEnemie(gameTime);
            ProcessCollisonBullet();
        }
        public void Draw()
        {
            //Ve player va mother ship
            for (int i = 0; i < listShip.Count; i++)
            {
                if (camera.BoudingVolumeslnView(listShip[i].BoudingSphere))
                {
                    listShip[i].Draw(camera.View, camera.Projection);
                }                              
            }
            //Ve enemie
            foreach (CModel eemie in listEnemie)
            {
                if (camera.BoudingVolumeslnView(eemie.BoudingSphere))
                {
                    eemie.Draw(camera.View,camera.Projection);
                }
            }
           
            //ve model check (neu can)
            if (Keyboard.GetState().IsKeyDown(Keys.LeftControl))
            {
                foreach (var check in listCheckShipMother)
                {
                    if (camera.BoudingVolumeslnView(check.BoudingSphere))
                    {
                        check.Draw(camera.View, camera.Projection);
                    }
                }
                foreach (var check in listCheckEnemies)
                {
                    if (camera.BoudingVolumeslnView(check.BoudingSphere))
                    {
                        check.Draw(camera.View, camera.Projection);
                    }
                }
            }
            //ve ground
            foreach (var ground in listGround)
            {
                if (camera.BoudingVolumeslnView(ground.BoudingSphere))
                {
                    ground.Draw(camera.View, camera.Projection);
                }
            }
            
        }

        private bool isBullet;
    }
}
